﻿using MediatR;
using Sgr.Application.Commands;
using Sgr.Identity.Services;
using Sgr.Security.VerifyCode;
using Sgr.UPMS.Domain.Users;

namespace Sgr.UPMS.Application.Commands.UserProfile
{
    public class ForgotPasswordCommandHandle : IRequestHandler<ForgotPasswordCommand, CommandResult<bool>>
    {
        private readonly IUserRepository _userRepository;
        private readonly IPasswordHashService _passwordHashService;
        private readonly IVerifyCodeService _verifyCodeService;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ForgotPasswordCommandHandle(
            IUserRepository userRepository,
            IPasswordHashService passwordHashService,
            IVerifyCodeService verifyCodeService)
        {
            _userRepository = userRepository ?? throw new ArgumentNullException(nameof(userRepository));
            _passwordHashService = passwordHashService ?? throw new ArgumentNullException(nameof(passwordHashService));
            _verifyCodeService = verifyCodeService ?? throw new ArgumentNullException(nameof(verifyCodeService));
        }

        public async Task<CommandResult<bool>> Handle(ForgotPasswordCommand request, CancellationToken cancellationToken)
        {
            // 1. 验证码校验
            bool isValidCode = await _verifyCodeService.VerifyAsync(
                request.AuthenticationType == UserAuthenticationType.PhoneNumber ? ReceiverType.Phone : ReceiverType.Email,
                request.Account,
                request.VerificationPurpose,
                request.VerificationCode,
                true,
                cancellationToken);

            if (!isValidCode)
            {
                return CommandResult.Invalid<bool>(Constant.INVALID_VERIFYCODE_MESSAGE);
            }

            // 2. 验证账号
            User? user;
            if (request.AuthenticationType == UserAuthenticationType.PhoneNumber)
            {
                user = await _userRepository.GetByPhoneAsync(request.Account, cancellationToken);
            }
            else
            {
                user = await _userRepository.GetByEmailAsync(request.Account, cancellationToken);
            }

            if (user == null)
            {
                return CommandResult.Invalid<bool>("用户不存在");
            }

            // 3. 重置密码
            user.ChangePassword(_passwordHashService, request.LoginPassword ?? Constant.DEFAULT_PASS_WORD);

            // 更新到仓储
            await _userRepository.UpdateAsync(user, cancellationToken);

            // 返回成功结果
            return CommandResult.Success(true, "密码重置成功");
        }
    }
}